package 中等.模拟;

/**
 * 给定一个字符串 queryIP。如果是有效的 IPv4 地址，返回 "IPv4" ；
 * 如果是有效的 IPv6 地址，返回 "IPv6" ；如果不是上述类型的 IP
 * 地址，返回 "Neither" 。
 * 有效的IPv4地址 是 “x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255
 *  且 xi 不能包含 前导零。例如: “192.168.1.1” 、 “192.168.1.0” 为有效
 * IPv4地址， “192.168.01.1” 为无效IPv4地址; “192.168.1.00” 、 “192.168@1.1”
 * 为无效IPv4地址。
 * 一个有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8” 的IP地址，其中:
 * 1 <= xi.length <= 4
 * xi 是一个 十六进制字符串 ，可以包含数字、小写英文字母( 'a' 到 'f' )和大
 * 写英文字母( 'A' 到 'F' )。
 * 在 xi 中允许前导零。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/validate-ip-address
 */
public class 验证IP地址_468 {

    public static void main(String[] args) {

        System.out.println(validIPAddress("2001:0db8:85a3:0:0:8A2E:0370:7334::::::"));

    }

    /**
     * 模拟
     *
     * @param queryIP
     * @return
     */
    public static String validIPAddress(String queryIP) {
        if (queryIP.contains(".")) {
            int count = 0;
            // 出现多个 ... 相邻时，split会只看作一个 .
            for (int i = 0; i < queryIP.length(); i++) {
                if (queryIP.charAt(i) == '.') count++;
            }
            if (count != 3) return "Neither";
            String[] split = queryIP.split("\\.");
            if (split.length != 4) return "Neither";
            for (String str : split) {
                if (!isIPV4(str)) return "Neither";
                if (count > 3) return "Neither";
            }
            return "IPv4";
        } else if (queryIP.contains(":")) {
            int count = 0;
            for (int i = 0; i < queryIP.length(); i++) {
                if (queryIP.charAt(i) == ':') count++;
                if (count > 7) return "Neither";
            }
            if (count != 7) return "Neither";
            String[] split = queryIP.split(":");
            if (split.length != 8) return "Neither";
            for (String str : split) {
                if (!isIPV6(str)) return "Neither";
            }
            return "IPv6";
        }
        return "Neither";
    }

    private static boolean isIPV6(String str) {
        if (str.length() > 4 || str.length() == 0) return false;
        for (int i = 0; i < str.length(); i++) {
            char cur = str.charAt(i);
            if (Character.isDigit(cur)) continue;
            if (cur >= 'a' && cur <= 'f') continue;
            if (cur < 'A' || cur > 'F') return false;
        }
        return true;
    }

    private static boolean isIPV4(String str) {
        if (str.length() > 3 || str.length() == 0) return false;
        if (str.charAt(0) == '0' && str.length() > 1) return false;
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isDigit(str.charAt(i))) return false;
        }
        Integer num = Integer.valueOf(str);
        return num >= 0 && num <= 255;
    }

}
